package org.jeecg.modules.iot.controller;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.iot.model.v20180120.PubResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.jeecg.modules.iot.aliyun.MessageBody;
import org.jeecg.modules.iot.bean.VersionInfo;
import org.jeecg.modules.iot.common.HttpResult;
import org.jeecg.modules.iot.message.ReceiveUpload;
import org.jeecg.modules.iot.service.IotDeviceService;
import org.jeecg.modules.iot.tools.ByteUtils;
import org.jeecg.modules.iot.tools.HttpServletUtils;
import org.jeecg.modules.iot.tools.JsonUtils;
import org.jeecg.modules.iot.tools.SignUtils;
import org.jeecg.modules.power.device.service.IYlDeviceService;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

import org.jeecg.modules.iot.aliyun.DeviceConfig;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author sunhuakaiaa
 * @since 2024-08-23
 */
@RestController
@Api(tags = "设备鉴权接口")
@Slf4j
@RequestMapping("/api")
public class ApiAuthController {

    @Autowired
    private IotDeviceService iotDeviceService;
    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 获取MQTT鉴权地址
     * https://help.aliyun.com/document_detail/73742.html?spm=a2c4g.11186623.6.587.69fa1bb8kGHsBc
     * 使用HTTPS认证再连接
     * @param uuid 设备名称
     * @return 阿里云返回设备的登录MQTT的账号和密码
     * @throws Exception 异常
     */
    @RequestMapping("/iot/client/con")
    @ApiOperation("鉴权接口")
    public HttpResult getIotDeviceConfig( @RequestParam(name="simUUID", defaultValue="") String simUUID,
                                          @RequestParam(name="simMobile", defaultValue="") String simMobile,
                                          @RequestParam(name="uuid", defaultValue="") String uuid,
                                          @RequestParam(name="ssl", defaultValue="1") String ssl,
                                          @RequestParam(name="sign", defaultValue="1") String sign,
                                          @RequestParam(name="deviceId", defaultValue="0")String deviceId) throws Exception {
        HttpResult httpResult = new HttpResult();
        MessageBody messageBody = new MessageBody();
        String url = HttpServletUtils.getRealUrl(true);
        messageBody.setMessageId("client_con");
        messageBody.setMessageType("http");
        messageBody.setTopic("GET：" + url);
        messageBody.setTimestamp(System.currentTimeMillis() / 1000);
        DeviceConfig config = iotDeviceService.getIotDeviceConfig(uuid);
        String[] arrStr = new String[]{config.getDeviceName(),
                config.getProductKey(),
                config.getHost(), String.valueOf(config.getPort()),
                config.getIotId(), config.getIotToken(),
                String.valueOf(System.currentTimeMillis())};
        String data = StringUtils.join(arrStr, ",");
        httpResult.setData(data);
        messageBody.setPayload(JsonUtils.toJson(httpResult));
        return httpResult;
    }

    @ApiOperation("还宝")
    @RequestMapping("/rentbox/order/return")
    public HttpResult powerbankReturn(@RequestParam(name="rentboxSN", defaultValue="") String rentboxSN,
                                      @RequestParam(name="singleSN", defaultValue="") String singleSN,
                                      @RequestParam(name="hole", defaultValue="0") String hole,
                                      @RequestParam(name="sign", defaultValue="1") String sign, HttpServletResponse response) throws Exception {
        HttpResult httpResult = new HttpResult();
        MessageBody messageBody = new MessageBody();
        try {
            //TEST LOG
            String url = HttpServletUtils.getRealUrl(true);
            messageBody.setMessageId("return powerbank");
            messageBody.setMessageType("http");
            messageBody.setTopic("GET：" + url);
            messageBody.setTimestamp(System.currentTimeMillis() / 1000);

//            this.checkSign(valid,valid.getSign());
            messageBody.setPayload(JsonUtils.toJson(httpResult));
        }
        catch (Exception e){
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            httpResult.setCode(response.getStatus());
            httpResult.setMsg(e.toString());
            messageBody.setPayload(e.toString());
        }
        finally {
//            mnsUtils.putMessageBody(messageBody);
            log.info("收到数据{rentboxSN：{} ，singleSN：{}，hole：{}，sign：{}}",rentboxSN,singleSN,hole,sign);
        }
        return httpResult;
    }

    @ApiOperation("整机上报")
    @RequestMapping("/rentbox/upload/data")
    public HttpResult rentboxOrderReturnEnd(@RequestBody byte[] bytes,
                                            @RequestParam String rentboxSN,
                                            @RequestParam String sign,
                                            @RequestParam(defaultValue = "0") String signal,
                                            HttpServletResponse response) throws Exception {
        HttpResult httpResult = new HttpResult();
        MessageBody messageBody = new MessageBody();
        try {
            //TEST LOG
            String data = ByteUtils.to16Hexs(bytes);
            String url = HttpServletUtils.getRealUrl(true);
            messageBody.setMessageId("upload data");
            messageBody.setMessageType("http");
            messageBody.setTopic("POST：" + url);
            messageBody.setPayload(data);
            messageBody.setTimestamp(System.currentTimeMillis() / 1000);
            Map params = new HashMap<>();
            params.put("rentboxSN", rentboxSN);
            params.put("signal", signal);
//            this.checkSign(params, sign);
            ReceiveUpload receiveUpload = new ReceiveUpload(bytes);
            messageBody.setPayload(JsonUtils.toJson(httpResult));
            log.info("收到整机上报的数据:{}", JSONObject.toJSONString(receiveUpload));
        }
        catch (Exception e){
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            httpResult.setCode(response.getStatus());
            httpResult.setMsg(e.toString());
            messageBody.setPayload(e.toString());
        }
        finally {
//            mnsUtils.putMessageBody(messageBody);
            iotDeviceService.uploadData(rentboxSN,messageBody);
            log.info("收到数据{rentboxSN：{} ，sign：{}}",rentboxSN,sign);
        }
        return httpResult;
    }

    @ApiOperation("设备配置信息接口")
    @RequestMapping("/rentbox/config/data")
    public HttpResult configData(@RequestParam(name="rentboxSN", defaultValue="") String rentboxSN,
                                 @RequestParam(name="dRotationEnable", defaultValue="") String dRotationEnable,
                                 @RequestParam(name="dRotationNumber", defaultValue="") String dRotationNumber,
                                 @RequestParam(name="dRotationRefer", defaultValue="") String dRotationRefer,
                                 @RequestParam(name="dMotorEnable", defaultValue="") String dMotorEnable,
                                 @RequestParam(name="dAreaConfig", defaultValue="") String dAreaConfig,
                                 @RequestParam(name="dHeadConfig", defaultValue="") String dHeadConfig,
                                 @RequestParam(name="sign", defaultValue="") String sign,
                                            HttpServletRequest request,
                                            HttpServletResponse response) throws Exception {
        HttpResult httpResult = new HttpResult();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("dRotationEnable","1");
        jsonObject.put("dRotationRefer","15");
        jsonObject.put("dMotorEnable","1");
        jsonObject.put("dAreaConfig","04");
        jsonObject.put("dHeadConfig","43");
        jsonObject.put("dReturnLocked","0");
//        String requestURL = "http://dasheng.16soft.cc/sw/api/rentbox/config/data?rentboxSN=864601068508480&dRotationEnable=1&dRotationNumber=4&dRotationRefer=15&dMotorEnable=15&dAreaConfig=0&dHeadConfig=43&sign=0c8735bea1a29a5dafa764aee79378aa";
//        String signs = SignUtils.getSign(requestURL);
//        CheckSignUtil.checkSign(jsonObject,sign);
        Integer number = iotDeviceService.getDevice(rentboxSN);
        jsonObject.put("dRotationNumber",number);
        httpResult.setData(jsonObject.toJSONString());
        return httpResult;
    }

    private VersionInfo getVersionInfo(String key){
        BoundValueOperations valueOps = redisTemplate.boundValueOps(key);
        VersionInfo versionInfo = (VersionInfo) valueOps.get();
        if(versionInfo == null){
            versionInfo = new VersionInfo();
        }
        return versionInfo;
    }
    /**
     * 返回最新版本(MCU)
     * @return 新版本地址
     */
    @ApiOperation("设备在线升级mcu")
    @RequestMapping("/iot/app/version/publish/mcu")
    public HttpResult iotAppVersionPublichMcu(@RequestParam String appUuid,
                                              @RequestParam(defaultValue = "") String deviceUuid,
                                              @RequestParam String sign,
                                              HttpServletResponse response){
        HttpResult httpResult = new HttpResult();
        MessageBody messageBody = new MessageBody();
        try {
            //TEST LOG
            String url = HttpServletUtils.getRealUrl(true);
            messageBody.setMessageId("publish/mcu");
            messageBody.setMessageType("http");
            messageBody.setTopic("GET：" + url);
            messageBody.setTimestamp(System.currentTimeMillis() / 1000);

            Map map = new HashMap();
            map.put("appUuid",appUuid);
            map.put("deviceUuid",deviceUuid);
            map.put("sign",sign);
//            this.checkSign(map, sign);
            VersionInfo versionInfo = getVersionInfo("versionInfo_mcu");
            httpResult.setData(versionInfo.getMcuRelease());
            messageBody.setPayload(JsonUtils.toJson(httpResult));
        }
        catch (Exception e){
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            httpResult.setCode(response.getStatus());
            httpResult.setMsg(e.toString());
            messageBody.setPayload(e.toString());
        }
        finally {
//            mnsUtils.putMessageBody(messageBody);
        }
        return httpResult;
    }

    /**
     * 返回最新版本(chip)
     * @return 新版本地址
     */
    @ApiOperation("设备在线升级chip")
    @RequestMapping("/iot/app/version/publish/chip")
    public HttpResult iotAppVersionPublichChip(@RequestParam String appUuid,
                                              @RequestParam(defaultValue = "") String deviceUuid,
                                              @RequestParam String sign,
                                              HttpServletResponse response){
        HttpResult httpResult = new HttpResult();
        MessageBody messageBody = new MessageBody();
        try {
            //TEST LOG
            String url = HttpServletUtils.getRealUrl(true);
            messageBody.setMessageId("publish/mcu");
            messageBody.setMessageType("http");
            messageBody.setTopic("GET：" + url);
            messageBody.setTimestamp(System.currentTimeMillis() / 1000);

            Map map = new HashMap();
            map.put("appUuid",appUuid);
            map.put("deviceUuid",deviceUuid);
            map.put("sign",sign);
//            this.checkSign(map, sign);
            VersionInfo versionInfo = getVersionInfo("versionInfo_chip");
            httpResult.setData(versionInfo.getMcuRelease());
            messageBody.setPayload(JsonUtils.toJson(httpResult));
        }
        catch (Exception e){
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            httpResult.setCode(response.getStatus());
            httpResult.setMsg(e.toString());
            messageBody.setPayload(e.toString());
        }
        finally {
//            mnsUtils.putMessageBody(messageBody);
        }
        return httpResult;
    }

    /**
     * 返回最新版本(MCU)"versionInfo_mcu"
     * 返回最新版本(chip)"versionInfo_chip"
     * @return 新版本地址
     */
    @ApiOperation("设备最新版本固件地址")
    @RequestMapping("/setNewVersion")
    public void setNewVersion(String name,String length,String url,String key){
        VersionInfo versionInfo = new VersionInfo();
        String mcuRelease = new StringJoiner(",").add(name).add(length).add(url).toString();
        versionInfo.setMcuRelease(mcuRelease);
        BoundValueOperations valueOps = redisTemplate.boundValueOps(key);
        valueOps.set(versionInfo);
    }


    /**
     * @return 新版本地址
     */
    @ApiOperation("发送测试消息")
    @RequestMapping("/sendMessage")
    public PubResponse sendMessage(String sn,String message) throws ClientException {
        PubResponse response =  iotDeviceService.sendMsgAsync(sn,message,1);
        return response;
    }

    /**
     *
     * @return
     */
    @ApiOperation("转接")
    @RequestMapping(value = "/turnToLogin", method = RequestMethod.POST)
    public ModelAndView turnToLogin(String params){
        Map<String,Object> param = new HashMap<>();
        param.put("name","Jack");
        param.put("params",params);
        return new ModelAndView("https://www.baidu.com",param);
    }

}
